package com.bidevalution.core.util;

import com.bidevalution.core.Common;
import com.bidevalution.core.constant.CharConstant;
import com.qtp.core.model.Response;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author huyiqi
 */
public class HttpClientUtil {
    private static final Logger log = LoggerFactory.getLogger(HttpClientUtil.class);

	/**
     * 带参数的post请求
     *
     * @param url
     * @param map
     * @return
     * @throws Exception
     */
    public static  String doPost(String url, Map<String, String> map) throws Exception {
        // 声明httpPost请求
         HttpPost httpPost = new HttpPost(url);
         //配置超时时间
         RequestConfig requestConfig = RequestConfig.custom().
                 setConnectTimeout(1000).setConnectionRequestTimeout(1000)
                 .setSocketTimeout(1000).setRedirectsEnabled(true).build();
         //设置超时时间
         httpPost.setConfig(requestConfig);
         httpPost.addHeader(new BasicHeader("Content­Type","application/json"));
         CloseableHttpClient httpClient = HttpClients.createDefault();
        // 判断map不为空
        if (map != null) {
            // 声明存放参数的List集合
            List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
 
            // 遍历map，设置参数到list中
            for (Map.Entry<String, String> entry : map.entrySet()) {
                params.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
            }
 
            // 创建form表单对象
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(params, "utf-8");
            formEntity.setContentType("application/json");
 
            // 把表单对象设置到httpPost中
            httpPost.setEntity(formEntity);
        }
 
        // 使用HttpClient发起请求，返回response
        CloseableHttpResponse response = httpClient.execute(httpPost);
 
        // 解析response封装返回对象httpResult
        if (response.getEntity() != null) {
        	return EntityUtils.toString(response.getEntity(), "UTF-8");
        }
        return null;
    }
    public static String doGet(String url) {
    	CloseableHttpClient httpCilent = HttpClients.createDefault();
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(5000)   //设置连接超时时间
                .setConnectionRequestTimeout(5000) // 设置请求超时时间
                .setSocketTimeout(5000)
                .setRedirectsEnabled(true)//默认允许自动重定向
                .build();
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(requestConfig);
        try {
            HttpResponse httpResponse = httpCilent.execute(httpGet);
            if(httpResponse.getStatusLine().getStatusCode() == 200){
                return  EntityUtils.toString(httpResponse.getEntity());//获得返回的结果
            
            }else{
                return null;
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }finally {
            try {
                httpCilent.close();
            } catch (IOException e) {
                log.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public static void main(String[] args) throws IOException {
//        downloadFile("http://192.168.8.237:6084/qtp-file-server/UploadedFile/e44d280b-af2f-4769-8943-04ee0c4acfcf");
    }
    /**
     * 根据url下载文件
     * @param url 下载地址
     * @param localPath 保存到本地的路径
     * @return 返回文件绝对路径
     * @throws IOException
     */
    public static Response<String> downloadFile(String url, String localPath) throws IOException {
        HttpClient client = new HttpClient();
        InputStream in = null;
        OutputStream os = null;
        //建立连接
        GetMethod method = new GetMethod(url);
        //执行url请求
        try {
            client.executeMethod(method);
            //获取文件
            in = method.getResponseBodyAsStream();
            int status = method.getStatusCode();
            if(HttpStatus.SC_OK == status) {
                String name = getFileName(method);
                log.info("======下载成功======");
                //====将流保存到本地文件====
                name = switchFileName(name);
                localPath = Common.splicePath(localPath, name);
                log.info("======准备写入本地，路径为：" + localPath + "======");
                File file = new File(localPath);
                if(!file.getParentFile().exists()) {
                    boolean dirResult = file.getParentFile().mkdirs();
                    if(!dirResult) {
                        return Response.fail("创建文件路径时出错");
                    }
                }

                os = new FileOutputStream(file);
                byte[] buff = new byte[1024];
                int readed;
                while ((readed = in.read(buff)) > 0) {
                    os.write(buff, 0, readed);
                }
                os.flush();
                log.info("======写入本地文件成功======");
                return Response.ok(localPath);
            } else {
                log.info("======下载失败======");
                return Response.fail("下载失败");
            }
        } catch (Exception e) {
            method.releaseConnection();
            log.info("======下载出错======", e);
            throw e;
        } finally {
            if(in != null) {
                in.close();
            }
            if(os != null) {
                os.close();
            }
        }
    }

    /**
     * 根据url获取文件信息
     * @param url 文件下载地址
     * @return 返回文件名和文件二进制流
     */
    public static Map<String, byte[]> getRemoteFileBytes(String url) {
        HttpClient client = new HttpClient();
        InputStream in = null;
        Map<String, byte[]> result = new HashMap<>(2);
        //建立连接
        GetMethod method = new GetMethod(url);
        //执行url请求
        try {
            client.executeMethod(method);
            //获取文件
            in = method.getResponseBodyAsStream();
            int status = method.getStatusCode();
            if(HttpStatus.SC_OK == status) {
                String name = getFileName(method);
                byte[] binary = null;
                byte[] buff = new byte[1024];
                while (in.read(buff)>0) {
                    binary = ArrayUtils.addAll(binary, buff);
                }
                result.put(name, binary);
            }

        } catch (Exception e) {
            log.error("获取远程文件失败：", e);
        } finally {
            method.releaseConnection();
            if(in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error("关闭流时发生错误");
                }
            }
        }
        return result;
    }

    /**
     * 从响应头中获取文件名称
     * @param method http请求方法
     * @return 返回文件名称
     */
    private static String getFileName(GetMethod method) {
        String fileName = UUID.randomUUID().toString();
        Header header = method.getResponseHeader("Content-Disposition");
        String reg0 = "attachment;filename=\"(.*)\"";
        String reg = "attachment;filename=(.*)";
        Pattern pattern = Pattern.compile(reg0);
        Matcher match = pattern.matcher(header.getValue());
        if(match.find()) {
            fileName = match.group(1);
        } else {
            pattern = Pattern.compile(reg);
            match = pattern.matcher(header.getValue());
            if(match.find()) {
                fileName = match.group(1);
            }
        }
        return fileName;
    }

    /**
     * 将文件名转换为uuid的形式
     * @param fileName 原始文件名
     * @return 返回转换后的文件名
     */
    private static String switchFileName(String fileName) {
        String nameFormat = "%s.%s";
        if(StringUtils.isNotBlank(fileName)) {
            String[] names = fileName.split(CharConstant.CHAR_DOT);
            if(names.length > 1) {
                fileName = String.format(nameFormat, UUID.randomUUID().toString(), names[names.length-1]);
            }
        }
        return fileName;
    }
}
